package cate.game.pvp.eliterace;

import cate.game.framework.ModuleMan;
import cate.game.pvp.eliterace.data.EliteRaceKV;
import cate.game.pvp.eliterace.handler.*;
import cate.game.pvp.eliterace.simulator.*;
import cate.game.pvp.eliterace.timer.EliteRaceTimerTask;
import cate.game.pvp.eliterace.timer.EliteRaceTimerTask.Settings;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;


public class EliteRaceSimulatorManager extends ModuleMan
        implements EliteRaceTimerTask.SettingsFunctionSelector {

    private final EliteRaceSimulatorSelector simulatorSelector;

    public EliteRaceSimulatorManager(Supplier<EliteRaceKV> kvSupplier,
                                     Supplier<EliteRacePsOperation> psOperationSupplier,
                                     Supplier<EliteRaceRecordOperation> reportOperationSupplier,
                                     Supplier<EliteRaceFightOperation> fightOperationSupplier,
                                     Supplier<EliteRaceRankRwdOperation> rankRwdOperationSupplier,
                                     Supplier<EliteRaceBetOperation> betOperationSupplier,
                                     Supplier<EliteRaceRankHandler> rankHandlerSupplier,
                                     Supplier<EliteRaceExcelQueryOperation> excelQueryOperationSupplier,
                                     Supplier<EliteRaceVideoOperation> videoOperationSupplier) {
        this.simulatorSelector = new BothEliteRaceSimulatorSelector(
                this.buildSimulatorList(
                        kvSupplier,
                        psOperationSupplier,
                        reportOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        rankHandlerSupplier,
                        excelQueryOperationSupplier,
                        videoOperationSupplier
                )
        );
    }

    @Override
    public Function<Settings, Boolean> select(Settings settings) {
        return Optional.of(settings)
                .map(this.simulatorSelector::select)
                .map(EliteRaceSimulator::getSettingsFunction)
                .orElse(s -> true);
    }

    private List<EliteRaceSimulator> buildSimulatorList(
            Supplier<EliteRaceKV> kvSupplier,
            Supplier<EliteRacePsOperation> psOperationSupplier,
            Supplier<EliteRaceRecordOperation> reportOperationSupplier,
            Supplier<EliteRaceFightOperation> fightOperationSupplier,
            Supplier<EliteRaceRankRwdOperation> rankRwdOperationSupplier,
            Supplier<EliteRaceBetOperation> betOperationSupplier,
            Supplier<EliteRaceRankHandler> rankHandlerSupplier,
            Supplier<EliteRaceExcelQueryOperation> excelQueryOperationSupplier,
            Supplier<EliteRaceVideoOperation> videoOperationSupplier) {
        return Lists.newArrayList(
                new BothEliteRaceControlSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceGroupSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceTrialSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceKoSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceFinalSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceBetRwdSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceReadySimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        videoOperationSupplier
                ),
                new BothEliteRaceRankRwdSimulator(
                        kvSupplier,
                        reportOperationSupplier,
                        psOperationSupplier,
                        fightOperationSupplier,
                        rankRwdOperationSupplier,
                        betOperationSupplier,
                        rankHandlerSupplier,
                        excelQueryOperationSupplier,
                        videoOperationSupplier
                )
        );
    }

    @Override
    public void initDependent() throws Exception {
    }
}
